iT邦幫忙

2022 iThome 鐵人賽

DAY 23
1

我們在 D10 - Database by Docker 時,介紹了如何透過架設 MySQL,
不過,當我們要把應用程式跟資料庫連接起來時,還是很容易會遇到問題,

因此今天來說說,要如何讓 Express 的 API 使用架好的資料庫。


套件

要在 Server 上連接資料庫,Node.JS 的生態系中有很多套件可以使用,
我們今天用 Sequelize 當作範例,
除了 sequelize 套件以外,還會需要安裝資料庫的驅動,MySQL 對應的是 mysql2 套件。


Config

我們會需要定義 Sequelize 要使用的 Config,同時 Config 的值是讀取 .env 的內容:

# config/config.js

export default {
  development: {
    dialect: 'mysql',
    username: process.env.DB_USERNAME,
    password: process.env.DB_PASSWORD,
    database: process.env.DB_DATABASE,
    host: process.env.DB_HOST,
    port: process.env.DB_PORT,
  }
}
DB_HOST=host.docker.internal
DB_PORT=3306
DB_DATABASE=ithelp
DB_USERNAME=louis
DB_PASSWORD=my-password

DB_ROOT_PASSWORD=root-password

這裡要注意一個小細節,
我們等等要讓程式是透過 Port 3306 去連接 MySQL,
因此要讓 Container 內可以連接到主機本身的 Port,

這裡必需把 Container 內要使用的 DB_HOST 定義為 host.docker.internal

(官方文件可參考: I want to connect from a container to a service on the host)


API

為了測試與資料庫的連接,我們直接定義一個 API 的內容是對資料庫的一筆 Query,
然而,這時資料庫都還沒有內容,因此不用查詢真實的資料,而是透過 MySQL 幫我們回傳 1+1 就可以了,
只要 MySQL 有回傳加起來的結果,那就表示連接成功,即使沒有資料也可以測試,

import Router from 'express';
import { Sequelize } from 'sequelize';
import config from '../config/config.js';

const router = Router();

const sequelize = new Sequelize(config.development);

router.get('/test-connection', async (_, res) => {
	const result = await sequelize.query('select 1+1');
	return res.json({ result });
});


export default router;

Docker Compose

再次來到 Docker compose 的定義檔,
我們要定義兩個 Container,一個是 MySQL,另一個則是 Express,

version: "3"
services:
  mysqldb:
    image: mysql:8
    ports:
      - ${DB_PORT}:3306
    environment:
      - MYSQL_RANDOM_ROOT_PASSWORD=yes
      - MYSQL_ROOT_HOST=${DB_HOST}
      - MYSQL_DATABASE=${DB_DATABASE}
      - MYSQL_USER=${DB_USERNAME}
      - MYSQL_PASSWORD=${DB_PASSWORD}
    volumes:
      - ./db:/var/lib/mysql

  express:
    build: .
    ports:
      - 3000:3000
    env_file:
      - .env
    extra_hosts:
      - "host.docker.internal:host-gateway"

這裡有第二個小細節,
在 Docker Compose 要讓 DB_HOST=host.docker.internal 能順利生效,我們必須要在加入一個特殊的參數: extra_hosts

接著就能跑起來了:

$ docker compose up -d

$ curl http://localhost:3000/test-connection

{"result":[[{"1+1":2}],[{"1+1":2}]]}%

看到了執行結果 1+1 = 2,
我們並沒有在程式內運算 1+1,而是下了 SQL 語法讓 MySQL 幫我們計算,

因此我們藉此確認 Express 跟資料庫已經順利連接 ?,

後續,就能比較安心地開始開發了,

那我們今天就到這邊,範例程式碼可以在 這裡 找到。


上一篇
D22 - MongoDB by Docker
下一篇
D24 - Log
系列文
其實沒有那麼難 — Docker30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言